//! 数组
//!
//! 如果元素类型允许，任何大小的数组都实现了一下trait：
//! - Copy
//! - Clone
//! - Debug
//! - IntoIterator (为 [T; N]、&[T; N] 和 &mut [T; N] 实现)
//! - PartialEq, PartialOrd, Eq, Ord
//! - Hash
//! - AsRef, AsMut
//! - Borrow, BorrowMut
//!
#![allow(dead_code)]

pub struct ArrayLrn {}

impl ArrayLrn {
    pub fn hello() {
        println!("Array learning!");
    }
}

#[cfg(test)]
mod tests {
    #[allow(unused)]
    use super::*;

    #[test]
    fn test_basic() {
        let mut arr = [1, 2, 3];
        assert_eq!(arr[0], 1);
        assert_eq!(arr[1], 2);
        assert_eq!(arr[2], 3);
        arr[0] = 10;
        assert_eq!(arr[0], 10);
    }

    #[test]
    fn test_slice() {
        let arr = [1, 2, 3, 4, 5, 6];
        assert_eq!(arr[..], [1, 2, 3, 4, 5, 6]);
        assert_eq!(arr[1..2], [2]);
        assert_eq!(arr[..4], [1, 2, 3, 4]);
    }

    #[test]
    /// map()
    ///
    fn test_map() {
        let x = [1, 2, 3];
        let y = x.map(|v| v + 1);
        assert_eq!(y, [2, 3, 4]);

        let x = [1, 2, 3];
        let mut temp = 0;
        let y = x.map(|v| {
            temp += 1;
            v * temp
        });
        assert_eq!(y, [1, 4, 9]);

        let x = ["Ferris", "Bueller's", "Day", "Off"];
        let y = x.map(|v| v.len());
        assert_eq!(y, [6, 9, 3, 3]);
    }

    #[test]
    #[allow(unused)]
    #[allow(clippy::no_effect)]
    /// closure and for_each()
    fn test_closure() {
        let mut arr = vec![1, 2, 3];
        (0..arr.len()).for_each(|i| arr[i] += 3);
        let mut index = 0;
        (0..arr.len()).for_each(|i| {
            arr[i] += 3;
            index += 1;
        });
        (0..arr.len()).for_each(|i| {
            arr[i] *= 2;
            index += 1;
        });
        // let x = arr.map(|v| {
        //     v + 3;
        //     1
        // });
        println!("{:?}", arr);
        println!("{:?}", index);
    }

    #[test]
    fn test_default() {
        let i: i8 = Default::default();
        assert_eq!(i, 0);
    }

    #[test]
    fn slice_special_test() {
        let mut s: String = String::new();
        "hello".clone_into(&mut s);

        let mut v: Vec<i32> = Vec::new();
        // WARN: clone_into() 使用array的切片, target 是&mut T
        [1, 2, 3, 4, 5][..3].clone_into(&mut v);
        // 下面的代码会报错,不是切片
        // &[1, 23, 4].clone_into(&mut v);
        println!("{:?}", v);

        println!("{:?}", &[1, 2, 13, 4, 5][..3]);
    }

    #[test]
    /// NOTE: convert type
    fn convert_test() {
        let var1 = 10i32;
        let var2: &i32 = &var1;
        let var3: i32 = *var2;
        let var4 = var3.to_string();
        // parse()是用来把string slice转为数字的
        let var5 = var4.parse::<i32>().unwrap();
        println!("var4: {}", var4);
        println!("var5: {}", var5);

        let arr = [1, 2, 3];
        let mut vec1 = arr.to_vec();
        let vec2 = vec![5; 3];
        vec1.append(&mut vec2.clone());
        let vec3: &[i32] = &vec1[2..];
        let vec4 = vec3.to_vec();
        let arr2: &[i32] = vec4.as_slice();
        println!("arr2: {:?}", arr2);
    }
}

